package com.yunke.common.security;

import cn.dev33.satoken.stp.StpUtil;
import com.yunke.common.exception.YunkeException;
import com.yunke.common.result.YunkeResultCode;

/**
 * 安全工具类
 * 封装常用的认证和权限操作
 * 
 * @author yunke
 * @since 1.0.0
 */
public class YunkeSecurityUtil {

    private YunkeSecurityUtil() {
        // 工具类不允许实例化
    }

    /**
     * 获取当前登录用户ID
     * 
     * @return 用户ID
     */
    public static Long getCurrentUserId() {
        try {
            return StpUtil.getLoginIdAsLong();
        } catch (Exception e) {
            throw new YunkeException(YunkeResultCode.USER_NOT_LOGIN);
        }
    }

    /**
     * 获取当前登录用户ID（字符串）
     * 
     * @return 用户ID字符串
     */
    public static String getCurrentUserIdAsString() {
        try {
            return StpUtil.getLoginIdAsString();
        } catch (Exception e) {
            throw new YunkeException(YunkeResultCode.USER_NOT_LOGIN);
        }
    }

    /**
     * 检查当前是否已登录
     * 
     * @return 是否已登录
     */
    public static boolean isLogin() {
        return StpUtil.isLogin();
    }

    /**
     * 检查当前是否已登录，如未登录则抛出异常
     */
    public static void checkLogin() {
        if (!StpUtil.isLogin()) {
            throw new YunkeException(YunkeResultCode.USER_NOT_LOGIN);
        }
    }

    /**
     * 获取当前用户Token
     * 
     * @return Token值
     */
    public static String getToken() {
        return StpUtil.getTokenValue();
    }

    /**
     * 获取当前用户Token剩余有效时间（秒）
     * 
     * @return 剩余有效时间
     */
    public static long getTokenTimeout() {
        return StpUtil.getTokenTimeout();
    }

    /**
     * 检查当前用户是否拥有指定权限
     * 
     * @param permission 权限标识
     * @return 是否拥有权限
     */
    public static boolean hasPermission(String permission) {
        if (!isLogin()) {
            return false;
        }
        try {
            StpUtil.checkPermission(permission);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 检查当前用户是否拥有指定权限，如没有则抛出异常
     * 
     * @param permission 权限标识
     */
    public static void checkPermission(String permission) {
        checkLogin();
        try {
            StpUtil.checkPermission(permission);
        } catch (Exception e) {
            throw new YunkeException(YunkeResultCode.PERMISSION_DENIED, "权限不足：" + permission);
        }
    }

    /**
     * 检查当前用户是否拥有指定角色
     * 
     * @param role 角色标识
     * @return 是否拥有角色
     */
    public static boolean hasRole(String role) {
        if (!isLogin()) {
            return false;
        }
        try {
            StpUtil.checkRole(role);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 检查当前用户是否拥有指定角色，如没有则抛出异常
     * 
     * @param role 角色标识
     */
    public static void checkRole(String role) {
        checkLogin();
        try {
            StpUtil.checkRole(role);
        } catch (Exception e) {
            throw new YunkeException(YunkeResultCode.PERMISSION_DENIED, "角色权限不足：" + role);
        }
    }

    /**
     * 用户登录
     * 
     * @param userId 用户ID
     */
    public static void login(Long userId) {
        StpUtil.login(userId);
    }

    /**
     * 用户登录（指定设备）
     * 
     * @param userId 用户ID
     * @param device 设备标识
     */
    public static void login(Long userId, String device) {
        StpUtil.login(userId, device);
    }

    /**
     * 用户退出登录
     */
    public static void logout() {
        if (isLogin()) {
            StpUtil.logout();
        }
    }

    /**
     * 强制指定用户下线
     * 
     * @param userId 用户ID
     */
    public static void kickout(Long userId) {
        StpUtil.kickout(userId);
    }

    /**
     * 强制指定用户下线（指定设备）
     * 
     * @param userId 用户ID
     * @param device 设备标识
     */
    public static void kickout(Long userId, String device) {
        StpUtil.kickout(userId, device);
    }

    /**
     * 检查指定用户是否已被踢下线
     * 
     * @param userId 用户ID
     * @return 是否被踢下线
     */
    public static boolean isKickout(Long userId) {
        // 检查用户是否在线
        return !StpUtil.isLogin(userId);
    }

    /**
     * 获取指定用户的Token值
     * 
     * @param userId 用户ID
     * @return Token值
     */
    public static String getTokenValueByUserId(Long userId) {
        return StpUtil.getTokenValueByLoginId(userId);
    }

    /**
     * 获取当前会话的剩余有效时间（秒）
     * 
     * @return 剩余有效时间
     */
    public static long getSessionTimeout() {
        return StpUtil.getSessionTimeout();
    }

    /**
     * 续签当前Token
     * 
     * @param timeout 续签时间（秒）
     */
    public static void renewTimeout(long timeout) {
        StpUtil.renewTimeout(timeout);
    }

    /**
     * 检查是否为同一用户
     * 
     * @param userId 要检查的用户ID
     * @return 是否为同一用户
     */
    public static boolean isSameUser(Long userId) {
        if (!isLogin()) {
            return false;
        }
        return getCurrentUserId().equals(userId);
    }

    /**
     * 检查是否为同一用户，如不是则抛出异常
     * 
     * @param userId 要检查的用户ID
     */
    public static void checkSameUser(Long userId) {
        checkLogin();
        if (!isSameUser(userId)) {
            throw new YunkeException(YunkeResultCode.PERMISSION_DENIED, "只能操作自己的数据");
        }
    }
} 